home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / www / webpage < prev   
Encoding:
Korn shell script  |  1997-08-26  |  15.0 KB  |  517 lines

  1. #!/bin/ksh
  2. # @(#) webpage.ksh 2.1 97/01/21
  3. # 94/11/16 john h. dubois iii (john@armory.com)
  4. # 96/01/08 Print a slightly more useful message if a non-option is entered.
  5. # 96/11/07 2.0 Added all options.
  6. # 96/11/29 2.1 Added CheckPerms and FixPerms
  7.  
  8. ### Start of kstat lib
  9. # @(#) kstat.ksh 1.0 96/11/29
  10. # 96/11/29 john h. dubois iii (john@armory.com)
  11.  
  12. # Make these print in octal
  13. typeset -i8  S_IFMT=8#0170000    # File type bitmask
  14. typeset -i8 S_IRWXU=8#0000700    # Owner perms bitmask
  15. typeset -i8 S_IRWXG=8#0000070    # Group perms bitmask
  16. typeset -i8 S_IRWXO=8#0000007    # Other perms bitmask
  17. typeset -i8 S_IFREG=8#0100000    # Reg file
  18. typeset -i8 S_IFBLK=8#0060000    # Block file
  19. typeset -i8 S_IFDIR=8#0040000    # Directory
  20. typeset -i8 S_IFCHR=8#0020000    # Char file
  21. typeset -i8 S_IFIFO=8#0010000    # Named pipe
  22. typeset -i8 S_IFNAM=8#0050000    # Special named file
  23. typeset -i8 S_IFLNK=8#0120000    # Symlink
  24. typeset -i8 S_ISUID=8#0004000    # setuid
  25. typeset -i8 S_ISGID=8#0002000    # setgid
  26. typeset -i8 S_ISVTX=8#0001000    # sticky bit
  27. typeset -i8 S_IRUSR=8#0000400    # owner read
  28. typeset -i8 S_IWUSR=8#0000200    # owner write
  29. typeset -i8 S_IXUSR=8#0000100    # owner execute
  30. typeset -i8 S_IRGRP=8#0000040    # group read
  31. typeset -i8 S_IWGRP=8#0000020    # group write
  32. typeset -i8 S_IXGRP=8#0000010    # group execute
  33. typeset -i8 S_IROTH=8#0000004    # other read
  34. typeset -i8 S_IWOTH=8#0000002    # other write
  35. typeset -i8 S_IXOTH=8#0000001    # other execute
  36.  
  37. typeset -i8 ls2mode
  38. # Usage: ls2mode ls-mode-field
  39. # Returns the file mode in ls2mode
  40. function ls2mode {
  41.     typeset perm nperm comp name=${0##*/}
  42.     typeset -i ptype ret
  43.  
  44.     typeset perm=$1
  45.  
  46.     nperm=${perm#?}
  47.     case "${perm%$nperm}" in
  48.     -) ret=S_IFREG;;
  49.     d) ret=S_IFDIR;;
  50.     l) ret=S_IFLNK;;
  51.     b) ret=S_IFBLK;;
  52.     c) ret=S_IFCHR;;
  53.     p) ret=S_IFIFO;;
  54.     s) ret=S_IFNAM;;
  55.     m) ret=S_IFNAM;;
  56.     *) print -ru2 -- "$name: unknown type character: ${perm%$nperm}"
  57.     return 2;;
  58.     esac
  59.     perm=$nperm
  60.  
  61.     for ptype in 6 3 0; do        # get perms for user, group and other
  62.     for wperm in r w xsStT; do    # strip off each mode letter
  63.         nperm=${perm#?}
  64.         # get next component of perms
  65.         comp=${perm%$nperm}
  66.         # Make sure each mode bit has one of the expected values for it
  67.         if [[ "$comp" != [-$wperm] ]]; then
  68.         print -u2 "$name: unrecognized permission character: $comp"
  69.         return 3
  70.         fi
  71.         case $comp in
  72.         -) ;;
  73.         r) ret='ret|4<<ptype';;
  74.         w) ret='ret|2<<ptype';;
  75.         [xst]) ret='ret|1<<ptype';;
  76.         esac
  77.         case $comp in
  78.         [sS]) [ ptype -eq 3 ] && ret='ret|S_ISGID' ||
  79.           ret='ret|S_ISUID'
  80.         ;;
  81.         [tT]) ret='ret|S_ISVTX';;
  82.         esac
  83.         perm=$nperm
  84.     done
  85.     done
  86.     ls2mode=ret
  87. }
  88.  
  89. typeset -i8 kstat_mode
  90. typeset -i kstat_nlink kstat_uid kstat_gid kstat_major kstat_minor kstat_size
  91.  
  92. # Usage: kstat file ...
  93. function kstat {
  94.     typeset file line IFS=" "
  95.     typeset -i n=0
  96.  
  97.     ls -lLnd "$@" | while read line; do
  98.     ls2mode $line
  99.     kstat_mode[n]=ls2mode
  100.     set -- $line
  101.     kstat_nlink[n]=$2
  102.     # store uid & gid because username and groupname may be ambiguous
  103.     kstat_uid[n]=$3
  104.     kstat_gid[n]=$4
  105.     case "$5" in
  106.     *,?*)
  107.         kstat_major[n]=${5%,*}
  108.         kstat_minor[n]=${5#*,}
  109.         kstat_size[n]=-1
  110.         ;;
  111.     *,)
  112.         kstat_major[n]=${5%,}
  113.         kstat_minor[n]=$6
  114.         kstat_size[n]=-1
  115.         shift
  116.         ;;
  117.     *)
  118.         kstat_major[n]=-1
  119.         kstat_minor[n]=-1
  120.         kstat_size[n]=$5
  121.         ;;
  122.     esac
  123.     kstat_date[n]="$6 $7 $8"
  124.     shift 8
  125.     kstat_name[n]="$*"
  126.     let n+=1
  127.     done
  128.     [ n -gt 0 ] && return 0 || return 1
  129. }
  130. ### End of kstat lib
  131.  
  132. function CheckPerms {
  133.     typeset home=$1 pageDir=$2 homePage=$3
  134.     typeset fail=false badFiles badDirs
  135.     typeset -i OXR="S_IXOTH|S_IROTH"
  136.  
  137.     kstat "$home" || return 1
  138.     if ((!(kstat_mode&S_IXOTH))); then
  139.     print -r \
  140. "Your home directory must be made executable by \"other\" in order for the
  141. web server to access it.  Use the 'Fix permissions' option, or the command:
  142. chmod o+x \$HOME
  143. "
  144.     fail=true
  145.     fi
  146.     kstat "$pageDir" || return 1
  147.     # require web dir to be publicly readable too because some web servers
  148.     # require that in order to locate default file if /~user/ is given.
  149.     if [ "kstat_mode&OXR" -ne OXR ]; then
  150.     print -r \
  151. "Your web directory ($pageDir) must be made
  152. executable & readable by \"other\" in order for the web server to access it.  
  153. Use the 'Fix permissions' option, or use the command:
  154. chmod o+rx $pageDir
  155. "
  156.     fail=true
  157.     fi
  158.     kstat "$homePage" || return 1
  159.     if ((!(kstat_mode&S_IROTH))); then
  160.     print -r \
  161. "Your home page must be made readable by \"other\" in order for the
  162. web server to access it.  Use the 'Fix permissions' option, or the command:
  163. chmod o+r $homePage
  164. "
  165.     fail=true
  166.     fi
  167.     cd "$pageDir" || return 1
  168.     badFiles=$(find . -type f ! -perm -004 -print)
  169.     if [ -n "$badFiles" ]; then
  170.     print -r \
  171. "Some files in your web directory ($pageDir)
  172. are not readable by the web server.  Any that are intended to be web-served
  173. should be made publicly readable with the command: chmod o+r filename
  174. where filename is the name of the file to be made publicly readable.
  175. Alternately, the 'Fix permissions' option may be used; this will make all
  176. files in your web directory publicly readable.  The names of the files 
  177. (relative to your web directory) that may need to be modified are:
  178. $badFiles
  179. "
  180.     fail=true
  181.     fi
  182.     badDirs=$(find . -type d ! -perm -001 -print)
  183.     if [ -n "$badFiles" ]; then
  184.     print -r \
  185. "Some directories under your web directory ($pageDir)
  186. are not executable by the web server.  Any that contain files that are intended
  187. to be web-served should be made publicly executable with the command:
  188. chmod o+x dir-name-name
  189. where dir-name is the name of the directory to be made publicly executable. 
  190. Alternately, the 'Fix permissions' option may be used; this will make all
  191. directories under your web directory publicly readable.  The names of the
  192. directories (relative to your web directory) that may need to be modified are:
  193. $badDirs
  194. "
  195.     fail=true
  196.     fi
  197.     $fail || print -r "The permissions on your web-served files are correct."
  198. }
  199.  
  200. function FixPerms {
  201.     typeset home=$1 pageDir=$2 homePage=$3
  202.     typeset -i OXR="S_IXOTH|S_IROTH"
  203.  
  204.     print -nr \
  205. "This will make your web directory ($pageDir)
  206. publicly readable and executable, your home directory and all directories under
  207. your web directory publicly executable, and all regular files in your web
  208. directory publicly readable.  Are you sure you want to do this? [y/n]: "
  209.     read response
  210.     if [[ "$response" != [yY]* ]]; then
  211.     print -r "Permissions fix aborted."
  212.     return
  213.     fi
  214.     print -r "Fixing permissions (names of modified files follow)..."
  215.     # Check whether home & page dir really need to be modified so that an
  216.     # accurate list of modified filenames can be printed.
  217.     kstat "$home" || return 1
  218.     if ((!(kstat_mode&S_IXOTH))); then
  219.     print -r "$home"
  220.     chmod a+x "$home"
  221.     fi
  222.     kstat "$pageDir" || return 1
  223.     if [ "kstat_mode&OXR" -ne OXR ]; then
  224.     print -r "$pageDir"
  225.     chmod a+rx "$pageDir"
  226.     fi
  227.     cd "$pageDir" || return 1
  228.     find . -type f ! -perm -004 -print -exec chmod a+r {} \;
  229.     find . -type d ! -perm -001 -print -exec chmod a+x {} \;
  230.     print "Done.\n"
  231. }
  232.  
  233. function MakePage {
  234.     print -u2 "Making prototype web page..."
  235.  
  236.     set -o noclobber    # just to be sure we don't overwrite anything
  237.  
  238.     if [ ! -d $HomePageDir ]; then
  239.     mkdir $HomePageDir || {
  240.         print -u2 "Could not make a directory for your web page."
  241.         exit 1
  242.     }
  243.     fi
  244.  
  245.     # Make the possessive form of NAME
  246.     [[ "$NAME" = *s ]] && PSName="$NAME'" || PSName="$NAME's"
  247.     # Create prototype user page, substituting in vars
  248.     if [ -f "$PROTOPAGE" -a -r "$PROTOPAGE" ]; then
  249.     cat $PROTOPAGE
  250.     else
  251.     print -r -- "$defPage"
  252.     fi | sed "
  253. s@%PSNAME%@$PSName@
  254. s@%NAME%@$NAME@
  255. s@%USER%@$USER@
  256. s@%URL%@$URL@
  257. s@%MAILNAME%@$MAILNAME@
  258. " > $HomePage
  259.  
  260.     chmod a+rx $Home $HomePageDir
  261.     chmod a+r $HomePage
  262.  
  263.     print \
  264. "A prototype home page has been created for you.  It is in the file:
  265. $HomePage
  266. You can edit the file and replace its contents with material of your own
  267. creation.  The URL for your web page is:
  268. $URL
  269. You can get information on HTML, URLs, etc. by selecting the 'Help' option
  270. within your web browser.
  271. "
  272. }
  273.  
  274. ### Start of main program
  275. # 95/12/23 john h. dubois iii (john@armory.com)
  276. # Usage: host2addr <hostname>
  277. # Sets global host2addr to first ip address associated with hostname
  278. # Return value: 0 on success, 1 on failure
  279. function host2addr {
  280.     typeset hostname=$1 name t ip
  281.  
  282.     if [[ "$hostname" = +([0-9])+(.+([0-9])) ]]; then
  283.     host2addr=$hostname
  284.     else
  285.     /etc/dig +pfset=0x2020 "$hostname" | while read name t ip; do
  286.         # Ignore CNAMEs and such.  dig will automatically look up the A
  287.         # record for the name the CNAME points to.
  288.         [ "$t" = A ] && break
  289.     done
  290.     [[ "$ip" != +([0-9])+(.+([0-9])) ]] && return 1
  291.     host2addr=$ip
  292.     fi
  293.     return 0
  294. }
  295.  
  296. # Usage: addr2host <addr>
  297. # Sets global addr2host to first hostname associated with addr
  298. # Return value: 0 on success, 1 on failure
  299. function addr2host {
  300.     typeset addr=$1 name t ip
  301.  
  302.     if [[ $# -eq 0 || "$1" != +([0-9.]) ]]; then
  303.     addr2host=
  304.     return 1
  305.     fi
  306.     /etc/dig +pfset=0x2020 -x "$addr" | while read ip t name; do
  307.     [ "$t" = PTR ] && break
  308.     done
  309.     [[ -z "$name" ]] && return 1
  310.     addr2host=$name
  311.     return 0
  312. }
  313.  
  314. l_name=${0##*/}
  315. Usage=\
  316. "Usage: $l_name [-h] [-e<editor>] [-g<graphical-browser>] [-t<text-browser>]
  317.        [-w<www-name>] [-m<mailname>] [-i<index-page>] [-d<homepage-directory>]
  318.        [-p<prototype-page>]"
  319.  
  320. defProtoPage=/usr/local/lib/protopage
  321. PROTOPAGE=$defProtoPage
  322. # save value of editor from environment, if any, so that config file won't
  323. # overwrite it
  324. if [ -n "$VISUAL" ]; then
  325.     sEDITOR=$VISUAL
  326. elif [ -n "$EDITOR" ]; then
  327.     sEDITOR=$EDITOR
  328. fi
  329.  
  330. TBROWSER=lynx
  331. GBROWSER=Mosaic
  332. INDEXPAGE=index.html
  333. PAGEDIR=.public_html
  334. defFile=/etc/default/webpage
  335. defPage="<title>%PSNAME% WWW Home Page</title>
  336. <h1>%PSNAME% WWW Home Page</h1>
  337. This is a prototype web page for %NAME%.
  338. <hr>
  339. This web page maintained by <a href=%URL%>
  340. %USER%@%MAILNAME%</a>"
  341. userDefFile=.webpage
  342. [ -f $defFile -a -r $defFile ] && . $defFile
  343. [ -f $HOME/$userDefFile -a -r $HOME/$userDefFile ] && . $HOME/$userDefFile
  344.  
  345. if [ -n "$sEDITOR" ]; then
  346.     EDITOR=$sEDITOR
  347. elif [ -z "$EDITOR" ]; then
  348.     EDITOR=vi
  349. fi
  350.  
  351.  
  352. while getopts he:g:t:w:m:i:d:p: opt; do
  353.     case $opt in
  354.     h)
  355.     print -r -- \
  356. "$l_name: create, view, or modify a user-maintained web page.
  357. $l_name creates a web page directory for the invoking user, puts a prototype
  358. home page in it, and then lets the user view and modify the page.
  359. For viewing the page, $l_name uses Mosaic if the user is on an X display, and
  360. lynx if not.  If the VISUAL or EDITOR environment variables are set, they are
  361. used to get the name of the editor to invoke.  If not, vi is used.
  362. $l_name will only invoke the editor on the top (index) page.  It tells the user
  363. the location of the web page directory so that the user can create a more
  364. complex web site directly.
  365. To get the hostname of the local system for use in URLs, $l_name first tries
  366. replacing the leftmost component of the local hostname with \"www\".  If this
  367. gives the same IP address as the unmodified hostname, it is used; otherwise
  368. the unchanged hostname is used.
  369. $l_name depends on the web server interpreting a URL of the form /~username/
  370. as a reference to a file named index.html in the user's home page directory
  371. within their UNIX home directory.  The default home page directory is
  372. \".public_html\".
  373. To generate the prototype web page, $l_name reads the file $defProtoPage
  374. and makes the following substitutions in it:
  375. %PSNAME% is replaced with the possessive form of NAME (e.g. John DuBois ->
  376.     John DuBois')
  377. %NAME% is replaced with the name of the invoking user, from the NAME
  378.     environment variable.
  379. %USER% is replaced with the username of the invoking user, from the USER
  380.     environment variable.
  381. %URL% is replaced with the URL of the page being generated.
  382. %MAILNAME% is replaced by the hostname of the local system for mail purposes.
  383. If -m is not given, this is the same as the unmodified hostname.
  384. The default is:
  385. $defPage
  386. <br>
  387. $Usage
  388. Options:
  389. Some of the following options can also be set by assigning values to variables
  390. in either of two configuration files.  First, $defFile is read;
  391. then the file named $userDefFile in the invoking user's home directory is read. 
  392. Assignments in the latter override assignments in the former.  In these files,
  393. values are assigned to variables in shell style, e.g. \"VARNAME=value\". 
  394. Variable names are given in parentheses following option descriptions.
  395. -h: Print this help.
  396. -e<editor>: Use <editor> to edit the page.  (EDITOR)
  397. -g<graphical-browser>: Use <graphical-browser> as the browser if on an X
  398.     display.  (GBROWSER)
  399. -t<text-browser>: Use <text-browser> as the browser if on a text display.
  400.     (TBROWSER)
  401. -w<www-name>: Set the hostname of the local system, for use in URLs, to
  402.     <www-name>.  (WWWNAME)
  403. -m<mailname>: Set the hostname of the local system for use in email addresses
  404.     to <mailname>.  (MAILNAME)
  405. -i<index-page>: Set the filename of the index page to <index-page> instead of
  406.     index.html.  (INDEXPAGE)
  407. -d<homepage-directory>: Set the homepage directory to <homepage-directory>;
  408.     this should the name of the directory under each user's UNIX home directory
  409.     in which the web server will look for /~username/ URLs.  (PAGEDIR)
  410. -p<prototype-page>: Set the filename of the web page prototype to
  411.     <prototype-page>.  (PROTOPAGE)"
  412.     exit 0
  413.     ;;
  414.     d)
  415.     PAGEDIR=$OPTARG
  416.     ;;
  417.     e)
  418.     EDITOR=$OPTARG
  419.     ;;
  420.     g)
  421.     GBROWSER=$OPTARG
  422.     ;;
  423.     i)
  424.     INDEXPAGE=$OPTARG
  425.     ;;
  426.     m)
  427.     MAILNAME=$OPTARG
  428.     ;;
  429.     p)
  430.     PROTOPAGE=$OPTARG
  431.     ;;
  432.     t)
  433.     TBROWSER=$OPTARG
  434.     ;;
  435.     w)
  436.     WWWNAME=$OPTARG
  437.     ;;
  438.     ?)
  439.     print -r -u2 "Use -h for help."
  440.     exit 1
  441.     ;;
  442.     esac
  443. done
  444.  
  445. # remove args that were options
  446. let OPTIND=OPTIND-1
  447. shift $OPTIND
  448.  
  449. HomePageDir="$HOME/$PAGEDIR"
  450. HomePage="$HomePageDir/$INDEXPAGE"
  451. [ -z "$DISPLAY" ] && browser=$TBROWSER || browser=$GBROWSER
  452. if [ -z "$WWWNAME" ]; then
  453.     # Try to get the best name for web purposes.
  454.     # If the local system's domain name with the host name replaced with 'www'
  455.     # gives the same ip address as the hostname does, use it; else use the
  456.     # original domain name.
  457.     hostname=$(hostname)
  458.     wwwname_maybe=www.${hostname#*.}
  459.     WWWNAME=$hostname
  460.     if host2addr "$hostname"; then
  461.     ip=$host2addr
  462.     if host2addr "$wwwname_maybe"; then
  463.         [ $host2addr = $ip ] && WWWNAME=$wwwname_maybe
  464.     fi
  465.     fi
  466. fi
  467. if [ -z "$MAILNAME" ]; then
  468.     [ -z "$hostname" ] && hostname=$(hostname)
  469.     MAILNAME=$hostname
  470. fi
  471.  
  472. URL=http://$WWWNAME/~$USER/
  473.  
  474. if [ -f $HomePage ]; then
  475.     print \
  476. "You already have a web page.  The file name is:
  477. $HomePage
  478. The URL is: $URL
  479. "
  480. else
  481.     MakePage
  482. fi
  483.  
  484. select ans in \
  485. "View your home page as HTML source" \
  486. "Edit your home page with $EDITOR" \
  487. "Look at your home page with $browser" \
  488. "Check the permissions on your web-served files" \
  489. "Fix the permissions on your web-served files" \
  490. "Quit"
  491. do
  492.     case "$ans" in
  493.     View*)
  494.     ${PAGER:-more} "$HomePage";;
  495.     Edit*)
  496.     "$EDITOR" "$HomePage";;
  497.     Look*)
  498.     "$browser" "$URL";;
  499.     Check*)
  500.     CheckPerms "$HOME" "$HomePageDir" "$HomePage";;
  501.     Fix*)
  502.     FixPerms "$HOME" "$HomePageDir" "$HomePage";;
  503.     Quit)
  504.     break 2;;
  505.     *)
  506.     case "$REPLY" in
  507.     [qQeExX]*)
  508.         break 2;;
  509.     *)
  510.         print -u2 \
  511.     "Please enter 1, 2, 3, or 4, or press return for a list of options.."
  512.         ;;
  513.     esac
  514.     ;;
  515.     esac
  516. done
  517.